﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Mvc;
using Management.Core;
using Management.Core.Permission;
using Management.Auxiliary;
using Management.Core.RolePermission;

namespace Management.Areas.Control.Controllers
{
    [AdminAuthorize]
    public class RoleController : Controller
    {
        private ManagementContext db = new ManagementContext();
        // GET: /Control/Role/
        public ActionResult Index()
        {
            return View(db.Role.ToList());
        }


        // GET: /Control/Role/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Role role = db.Role.Find(id);
            if (role == null)
            {
                return HttpNotFound();
            }
            return View(role);
        }

        // GET: /Control/Role/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: /Control/Role/Create
        // 为了防止“过多发布”攻击，请启用要绑定到的特定属性，有关 
        // 详细信息，请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "RoleID,Name,Created_at,Updated_at")] Role role)
        {
            role.Created_at = DateTime.Now;
            role.Updated_at = DateTime.Now;
            if (ModelState.IsValid)
            {
                db.Role.Add(role);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(role);
        }

        // GET: /Control/Role/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Role role = db.Role.Find(id);
            var controllers = db.Permission.GroupBy(u => u.Controller).Select(i => i.Key);
            
            ViewBag.controllers = controllers.ToList();
            if (role == null)
            {
                return HttpNotFound();
            }
            return View(role);
        }

        [HttpPost]
        public ActionResult getAction(string name, int roleid)
        {
            var actionslist = new List<Permission>();
            if (!string.IsNullOrEmpty(name))
            {
                if (RedisHelper.Get<List<Permission>>("controller" + name) == null || RedisHelper.Get<List<Permission>>("controller" + name).Count() == 0)
                {
                    var actions = db.Permission.Where(u => u.Controller == name).ToList();
                    RedisHelper.Set<List<Permission>>("controller" + name, actions, DateTime.Now.AddHours(1) - DateTime.Now);
                }
                actionslist = RedisHelper.Get<List<Permission>>("controller" + name);
            }
            
            if(RedisHelper.Get<List<int>>("roleid"+roleid) == null || RedisHelper.Get<List<int>>("roleid"+roleid).Count() == 0)
            {
                var hasPermissions = db.Role.Find(roleid).RolePermission.Select(u => u.PermissionID).ToList();
                RedisHelper.Set<List<int>>("roleid" + roleid, hasPermissions, DateTime.Now.AddHours(1) - DateTime.Now);
            }            
            
            var permissionlist = RedisHelper.Get<List<int>>("roleid" + roleid);
            return Json(new { _actions = actionslist, _permissions = permissionlist});
        }

       
        [HttpPost]        
        public ActionResult Edit(int? id,string name, int[] selectedRoles)
        {
            Response _res = new Response();
            if (id == null)
            {
                _res.Code = -1;
                _res.Message = "error";
                return Json(_res);
            }
            if(!string.IsNullOrEmpty(name))
            {
                RoleManager rm = new RoleManager();
                Role role = rm.Find((int)id);
                if (role.Name != name)
                {
                    role.Name = name;
                    role.Updated_at = DateTime.Now;
                    rm.Update(role);
                }
            }
            RolePermission rolePermission = new RolePermission();
            RolePermissionManager rpm = new RolePermissionManager();
            if(TryUpdateModel(rolePermission, "", new string[] {"PermissionID", "RoleID" }))
            {
                try
                {
                    RedisHelper.DelKey("roleid" + id);
                    
                    
                    if(selectedRoles == null)
                    {
                        var rolePermissions = rpm.FindList(u => u.RoleID == (int)id).ToList();
                        foreach (var item in rolePermissions)
                        {
                            rpm.Delete(u => u.RoleID == item.RoleID);
                        }
                    }
                    else
                    {
                        List<int> selectList = selectedRoles.ToList();
                        var rolePermissionIds = rpm.FindList(u => u.RoleID == (int)id).Select(r => r.PermissionID).ToList();
                        var permissions = db.Permission.Select(u => u.PermissionID).ToList();
                        foreach(var item in permissions)
                        {
                            if(selectedRoles.Contains(item))
                            {
                                if(!rolePermissionIds.Contains(item))
                                {
                                    rolePermission.PermissionID = item;
                                    rolePermission.RoleID = (int)id;
                                    rolePermission.Created_at = DateTime.Now;
                                    rolePermission.Updated_at = DateTime.Now;
                                    _res = rpm.Add(rolePermission);
                                }
                            }
                            else
                            {
                                rpm.Delete(u => u.RoleID == (int)id && u.PermissionID == item);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    _res.Code = 0;
                    _res.Message = ex.Message;
                }
            }
            return Json(_res);
        }

        // GET: /Control/Role/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Role role = db.Role.Find(id);
            if (role == null)
            {
                return HttpNotFound();
            }
            return View(role);
        }

        // POST: /Control/Role/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Role role = db.Role.Find(id);
            db.Role.Remove(role);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}
